package app.controllers.mobileweb;

import app.Const;
import app.interceptors.MobileWxMemberInterceptor;
import app.models.booking.DiningCategory;
import app.models.booking.DiningDialyStat;
import app.models.booking.DiningMarket;
import app.models.booking.DiningNums;
import app.models.booking.DiningRecord;
import app.models.booking.DiningSetting;
import app.models.booking.DiningTime;
import app.models.brand.Brand;
import app.models.brand.BrandStat;
import app.models.member.Member;
import com.github.sog.controller.AjaxMessage;
import com.github.sog.controller.BasicController;
import com.github.sog.libs.AppFunc;
import com.github.sog.validator.ValidatorKit;
import com.google.common.base.Strings;
import com.jfinal.aop.Before;
import com.jfinal.ext.kit.DateKit;
import com.jfinal.plugin.activerecord.tx.Tx;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * .
 * </p>
 *
 * @author Jerry Ou
 * @version 1.0 2014-05-24 13:05
 * @since JDK 1.6
 */
@Before(MobileWxMemberInterceptor.class)
public class DiningController extends BasicController {

    public void list() {
        /*String dinningFormat = JFinalApp.configuration.getProperty("app.dining.format", "7");
        String date = DateTime.now().toString("yyyy-MM-dd");*/
        //DateT.toStr(new Date())
        // List<Record> recordList = DiningBrand.dao.dateDining(date, Longs.tryParse(dinningFormat));
        // setAttr("recordList", recordList);
        //List<Brand> brands = Brand.dao.findByFormatAndBooking(Longs.tryParse(dinningFormat));
        List<Brand> brands = Brand.dao.findByCatetoryAndBooking(Const.REPAST, true);
        setAttr("recordList", brands);
        render("list.ftl");
    }

    public void item() {
        long brandId = getParaToLong("id", 0l);


        Brand record = Brand.dao.findWithFloor(brandId);
        if (record != null) {

            final String picture = record.getStr("picture");
            if (!Strings.isNullOrEmpty(picture)) {
                List<String> pics = AppFunc.COMMA_SPLITTER.splitToList(picture);
                setAttr("pics", pics);
            }

            //查询统计情况
            BrandStat brandStat = BrandStat.dao.findById(record.get("id"));
            setAttr("brandStat", brandStat);

            //查询预定市别
            List<DiningMarket> diningMarkets = DiningMarket.dao.findByBrandAndStatus(brandId, true);
            setAttr("diningMarkets", diningMarkets);
        }
        setAttr("brand", record);
        render("item.ftl");
    }

    /**
     * 预订
     * <p/>
     * １、验证相关参数
     * ２、判断当前品牌是否可以预订
     * ２、根据品牌和人数计算桌位
     * ３、查看当前品牌当前桌位在当前市别是否可以预订
     * ４、记录相关流水、并发送短信
     */
    @Before(Tx.class)
    public void book() {
        long mid = getParaToLong(Const.MEMBER_PARAM, 0l);
        long brandId = getParaToLong("brandId", 0l);
        int meal_num = getParaToInt("meal_num", 0);
        String booking_date = getPara("booking_date");
        String category = getPara("category");
        String name = getPara("name");
        String phone = getPara("phone");

        final boolean mobile = ValidatorKit.isMobile(phone);
        if (!mobile) {
            renderJson(AjaxMessage.failure("请输入正确的手机号码"));
            return;
        }

        if (meal_num == 0) {
            renderJson(AjaxMessage.failure("请输入就餐人数"));
            return;
        }

        Date now = new Date();

        Date date;
        try {
            date = DateTime.parse(booking_date, DateTimeFormat.forPattern(DateKit.dateFormat)).toDate();
        } catch (Exception e) {
            renderJson(AjaxMessage.failure("请输入正确就餐日期"));
            return;
        }
        Brand brand = Brand.dao.findById(brandId);
        if (brand == null) {
            renderJson(AjaxMessage.failure("请选择品牌"));
            return;
        }
        if (brand.getBoolean("booking") != null && !brand.getBoolean("booking")) {
            renderJson(AjaxMessage.failure("该品牌不可预订"));
            return;
        }

        //DiningTime diningTime = DiningTime.dao.findByBrandAndTime(brandId, date);
        DiningTime diningTime = DiningTime.dao.findByBrand(brandId);
        if (diningTime == null) {
            renderJson(AjaxMessage.failure("不在可预订时间内"));
            return;
        }
        if (!(diningTime.getTimestamp("start_time").before(now) && diningTime.getTimestamp("end_time").after(now))) {
            renderJson(AjaxMessage.failure("不在可预订时间内"));
            return;
        }
        //根据当前就餐人数查询桌位类型，可能存在多个，要将已经满的过滤掉
        List<DiningCategory> diningCategories = DiningCategory.dao.findByBrandAndMealNum(brandId, meal_num);
        if (diningCategories == null || diningCategories.isEmpty()) {
            renderJson(AjaxMessage.failure("无法查询到符合就餐人数的桌位"));
            return;
        }
        int tableCategory = -1;
        DiningDialyStat diningDialyStat = null;
        for (DiningCategory dc : diningCategories) { //查询桌位符合不符合
            int table_category = dc.getInt("id");
            diningDialyStat = DiningDialyStat.dao.findByBrandTableDialyCategory(brandId, table_category, date, category);
            if (diningDialyStat == null || diningDialyStat.getBoolean("booking_state")) {
                tableCategory = table_category;
                break;
            }
        }

        if (tableCategory == -1) { //所有桌位已经满了
            renderJson(AjaxMessage.failure("桌位已满，请更改就餐人数"));
            return;
        }


        DiningNums diningNums = DiningNums.dao.findByBrandAndCategorg(brandId, tableCategory);
        DiningSetting diningSetting = DiningSetting.dao.findByBrand(brandId);

        //判断当前会员是否超过了预订限制
        long memberDayCount = DiningRecord.dao.memberBookCount(mid, brandId, date);
        if (diningSetting != null) {
            final Integer dialy_degree = diningSetting.getInt("dialy_degree");
            if (dialy_degree == null || dialy_degree <= memberDayCount) {
                renderJson(AjaxMessage.failure("你已经达到最大预定次数，请更换日期"));
                return;
            }
        }

        //生成预定流水
        saveDiningRecord(mid, brandId, meal_num, category, name, phone, date, brand, tableCategory);

        //记录预订日统计
        saveDiningDialyStat(brandId, category, date, tableCategory, diningDialyStat, diningNums);

        //判断是否操作中南币
        operCurrency(mid, diningSetting);

        renderJson(AjaxMessage.ok("预定成功"));
    }

    private void operCurrency(long mid, DiningSetting diningSetting) {
        if (diningSetting != null) {
            int oper = diningSetting.getInt("oper");
            if (oper == 1) { //加
                double curreny = diningSetting.getDouble("currency");
                Member.dao.optCurrency(mid, true, curreny, Const.DINING_ADD);
            } else if (oper == -1) { //减
                double curreny = diningSetting.getDouble("currency");
                Member.dao.optCurrency(mid, false, curreny, Const.DINING_CUT);
            }
        }
    }

    private void saveDiningDialyStat(long brandId, String category, Date date, int tableCategory, DiningDialyStat diningDialyStat, DiningNums diningNums) {
        if (diningDialyStat == null) {
            diningDialyStat = new DiningDialyStat();
            diningDialyStat.set("brand", brandId);
            diningDialyStat.set("table_category", tableCategory);
            diningDialyStat.set("booking_degree", 1);
            diningDialyStat.set("stat_date", date);
            if (diningNums != null) {
                int num = diningNums.getInt("num");

                if (num <= 1) {
                    diningDialyStat.set("booking_state", false);
                } else {
                    diningDialyStat.set("booking_state", true);
                }
            } else {
                diningDialyStat.set("booking_state", true);
            }

            diningDialyStat.set("category", category);
            diningDialyStat.save();
        } else {
            int booking_degree = diningDialyStat.getInt("booking_degree");
            booking_degree = booking_degree + 1;
            diningDialyStat.set("booking_degree", booking_degree);
            if (diningNums != null) {
                int num = diningNums.getInt("num");

                if (num <= booking_degree) {
                    diningDialyStat.set("booking_state", false);
                } else {
                    diningDialyStat.set("booking_state", true);
                }
            } else {
                diningDialyStat.set("booking_state", true);
            }
            diningDialyStat.update();
        }
    }

    private void saveDiningRecord(long mid, long brandId, int meal_num, String category, String name, String phone,
                                  Date date, Brand brand, int tableCategory) {
        /*String voucher = RandomStringKit.randomNumeric(6); //"凭证号码";
        boolean b = SmsWsKit.membreDiningSend(phone, voucher, brand.getStr("name")); //发送短信*/

        DiningRecord.dao.record(mid, brandId, meal_num, category, name, phone, date, tableCategory, null, false);
    }

    public void ok() { }
}
